package com.wen.system.service.impl;

import cn.hutool.json.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.wen.common.pojo.system.User;
import com.wen.common.pojo.system.oauth.OAuthUser;
import com.wen.common.utils.ResponseResult;
import com.wen.system.mapper.OAuthUserMapper;
import com.wen.system.mapper.UserMapper;
import com.wen.system.service.OAuthService;
import lombok.extern.slf4j.Slf4j;
import me.zhyd.oauth.config.AuthDefaultSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.lang.Nullable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;

/**
 * 使用 @Transactional且在类中注入了自己会产生循环依赖分析：<p>
 * bean在创建过程中，循环依赖另外一个bean，而另外一个bean中引用了未初始化之前的当前bean。
 * 如果在初始化的时候对当前bean进行了替换，就会导致循环依赖的另外一个bean引用的当前bean与容器中的当前bean不一致，
 * 一个是替换之前的bean,一个是替换之后的bean。就会抛 BeanCurrentlyInCreationException 异常。
 * <p>
 * 备注：？？在UserServiceImpl中注入了该条件的bean就不抛异常了
 * <p>
 *  References :https://blog.csdn.net/weixin_43832505/article/details/108867230
 * <p>
 * @author devin <devinlive@163.com>
 * @version 1.0
 * @since 2023/08/31 16:25
 */
@Slf4j
@Service
public class OAuthServiceImpl implements OAuthService {

    @Autowired
    private UserMapper userMapper;
    @Autowired
    private OAuthUserMapper oAuthUserMapper;
    @Autowired
    private OAuthService self;

    @Override
    public User registerSysUserByOAuth(OAuthUser oAuthUser) {
        User sysUser = new User();
        sysUser.setAvatar(oAuthUser.getAvatar());
//        sysUser.setUserType(UserTypeEnum.GITEE.getValue());
//        sysUser.setUserSource(UserSourceEnum.GITEE.getValue());
//        sysUser.setUserStatus(UserStatusEnum.ENABLE.getValue());
        sysUser.setUserName((oAuthUser.getRawUserInfo()).getStr("login"));
        sysUser.setNickName(oAuthUser.getNickName());
        sysUser.setPassword("123456");
        sysUser.setEmail("tran");
        sysUser.setCreateTime(new Date());
        userMapper.insert(sysUser);
        return sysUser;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void addOAuthUser(JSONObject userInfoData) {
        // 根据第三方和第三方用户id唯一确定一个用户
        QueryWrapper<OAuthUser> wr = new QueryWrapper<>();
        wr.eq("provider", AuthDefaultSource.GITEE.getName());
        wr.eq("provider_user_id", userInfoData.get("id"));
        OAuthUser oAuthUser = oAuthUserMapper.selectOne(wr);
        if (oAuthUser == null) {
            // 如果没有 添加 ，并绑定sysUser
            OAuthUser newOAuthUser = new OAuthUser();
            newOAuthUser.setUserId(null);
            newOAuthUser.setProvider(AuthDefaultSource.GITEE.getName());
            newOAuthUser.setProviderUserId(userInfoData.getStr("id"));
            newOAuthUser.setAvatar(userInfoData.getStr("avatar_url"));
            newOAuthUser.setNickName(userInfoData.getStr("name"));
            newOAuthUser.setEmail(userInfoData.getStr("email"));
            newOAuthUser.setAccessToken("test");
            newOAuthUser.setRawUserInfo(userInfoData);
            oAuthUserMapper.insert(newOAuthUser);

            // 绑定用户
            bindOAuthUser(newOAuthUser, null);

        } else {
            // 更新
            oAuthUser.setEmail("update email");
            oAuthUser.setAccessToken("test up");
            oAuthUser.setRawUserInfo(userInfoData);
            oAuthUserMapper.updateById(oAuthUser);
        }

    }

    @Override
    public ResponseResult<?> bindOAuthUser(OAuthUser authUser, @Nullable User sysUser) {
        if (authUser == null) return ResponseResult.error("", "绑定OAuth用户失败！");

        // 有系统用户，将OAuthUser绑定到系统用户
        if (sysUser != null) {
            // 更新OAuthUser
            authUser.setUserId(sysUser.getId());
            oAuthUserMapper.updateById(authUser);
            return ResponseResult.success();
        }
        // 没有系统用户，判断authUser是否有绑定用户 ，没有注册新sysUser绑定，有绑定到之前sysUser
        if (authUser.getUserId() == null) {
            sysUser = self.registerSysUserByOAuth(authUser);
            authUser.setUserId(sysUser.getId());
            oAuthUserMapper.updateById(authUser);
        } else { // 同一用户换了种第三方方式
            log.info("warn ===> : {}", "没有sysUser 但是oAuthUser有绑定用户，不可能！");
            // 将新的OAuthUser绑定到已有用户
//                User bindUser = null;
//                bindUser = userService.getUserById(authUser.getUserId());
//                authUser.setUserId(bindUser.getId());
//                oAuthUserMapper.updateById(authUser);
//                return ResponseResult.success();
        }

        return ResponseResult.success();
    }

    @Override
    public List<OAuthUser> selectBindOAuth(User user) {
        //        Proxy.newProxyInstance(ROAuthServiceImpl.class.getClassLoader(), oAuthService.getClass().getInterfaces(), (proxy, method, args) -> method.invoke(oAuthService, args));
        return oAuthUserMapper.selectList(Wrappers.<OAuthUser>lambdaQuery().eq(OAuthUser::getUserId, user.getId()));
    }

}
